/////////////////////////////////////////////////////////////////////////////
// Name:        ax_activator_resource.cpp
// Purpose:     Resource activator classes
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"

#include "ax/ax_view.h"

#include "ax_resource/ax_module.h"
#include "ax_resource/ax_activator_resource.h"
#include "ax_resource/ax_resource_library.h"
#include "ax_resource/ax_menu_resource.h"

IMPLEMENT_DYNAMIC_CLASS( AxResourceLibraryActivator, AxActivator )

AxResourceLibraryActivator::AxResourceLibraryActivator(AxMenuItem* item, AxResourceLibrary* library, const wxArrayString& fields, const wxArrayString& values)
{
    Init();
    
    m_menuItem = item;
    m_fields = fields;
    m_values = values;
    m_library = library;
    m_type = Search_Fields;
}

AxResourceLibraryActivator::AxResourceLibraryActivator(AxMenuItem* item, AxResourceLibrary* library, AxResourceLibraryActivatorType type)
{
    Init();

    m_menuItem = item;
    m_library = library;
    m_type = type;
}

void AxResourceLibraryActivator::Init()
{
    m_type = Search_Fields;
    m_library = NULL;
}

void AxResourceLibraryActivator::Copy(const AxResourceLibraryActivator& activator)
{
    AxActivator::Copy(activator);

    m_fields = activator.m_fields;
    m_values = activator.m_values;
    m_library = activator.m_library;
}

AxMenu* AxResourceLibraryActivator::Activate(AxMenuController* WXUNUSED(controller), AxMenuItem* item)
{
    if (m_library)
    {
        AxResourceSet workingSet;

        if (m_type == Search_Fields)
        {
            if (m_fields.GetCount() > 0)
            {
                GetLibrary()->CreateWorkingSetFromSearch(workingSet, m_fields[0], m_values[0], axSEARCH_CONTAINS);
            }
            size_t i;
            for (i = 1; i < m_fields.GetCount(); i++)
            {
                GetLibrary()->ApplySearchToWorkingSet(workingSet, m_fields[i], m_values[i], axSEARCH_CONTAINS);
            }
        }
        else if (m_type == Search_All)
        {
            GetLibrary()->CreateFullWorkingSet(workingSet);
        }

        if (workingSet.GetCount() > 0)
        {
            AxMenu* menu = new AxMenu;
            menu->SetLabel(item->GetLabel());
            menu->SetDescription(item->GetDescription());

            size_t i;
            for (i = 0; i < workingSet.GetCount(); i++)
            {
                AxResource* resource = workingSet.GetResource(i);
                wxString title = resource->GetPropertyString(axPROPERTY_TITLE);
                if (title.IsEmpty())
                    title = wxT("<unknown>");
                wxString description = resource->GetLongDescription();
                if (description.IsEmpty())
                    description = resource->GetShortDescription();
                if (description.IsEmpty())
                    description = title;
                
                AxMenuItem* menuItem  = new AxMenuItem(title, description,
                    wxEmptyString, new AxResourceActivator(m_library, resource));
                menuItem->SetDynamic();
                menuItem->SetData(new AxMenuItemResourceData(resource));
                
                menu->AddItem(menuItem);
            }

            // Add an 'Up' item
            menu->AddItem(new AxGoUpMenuItem);

            return menu;
        }
    }
    return NULL;
}

/*
 * AxResourceActivator implementation.
 * Activates an individual resource.
 */

IMPLEMENT_DYNAMIC_CLASS( AxResourceActivator, AxActivator )

AxResourceActivator::~AxResourceActivator()
{
    if (m_specificActivator)
        delete m_specificActivator;
}

AxResourceActivator::AxResourceActivator(AxResourceLibrary* library, AxResource* resource)
{
    m_library = library;
    m_resource = resource;

    AxModuleList::Node *node;
    for ( node = AxModule::GetModules().GetFirst(); node; node = node->GetNext() )
    {
        AxActivator* specificActivator = node->GetData()->CreateActivator(library, resource);
        if (specificActivator)
        {
            m_specificActivator = specificActivator;
            break;
        }
    }
}

// Operations

void AxResourceActivator::Init()
{
    m_resource = NULL;
    m_library = NULL;
    m_specificActivator = NULL;
}

void AxResourceActivator::Copy(const AxResourceActivator& activator)
{
    AxActivator::Copy(activator);

    m_resource = activator.m_resource;
    m_library = activator.m_library;
    m_specificActivator = activator.m_specificActivator;
}

AxMenu* AxResourceActivator::Activate(AxMenuController* controller, AxMenuItem* item)
{
    if (m_specificActivator)
        return m_specificActivator->Activate(controller, item);
    else
        return NULL;
}

// Called when a menu is reactivated, for example by going up. This
// allows a view to be shown again, without generating all the menus.
bool AxResourceActivator::Reactivate(AxMenuController* controller, AxMenuItem* item)
{
    if (m_specificActivator)
        return m_specificActivator->Reactivate(controller, item);
    else
        return false;
}

// Called when the user selects an item, for example to describe the item
bool AxResourceActivator::Select(AxMenuController* controller, AxMenuItem* item)
{
    if (m_specificActivator)
        return m_specificActivator->Select(controller, item);
    else if (controller->GetViewManager() && controller->GetViewManager()->GetDescriptionCtrl())
    {
        AxMenuItemResourceData* data = wxDynamicCast(item->GetData(), AxMenuItemResourceData);
        if (data && data->GetResource())
        {
            wxString description = data->GetResource()->GetShortDescription();
            if (description.IsEmpty())
                description = data->GetResource()->GetPropertyString(axPROPERTY_TITLE);

            controller->GetViewManager()->GetDescriptionCtrl()->SetValue(description);
        }
        else
        {
            controller->GetViewManager()->GetDescriptionCtrl()->SetValue(item->GetDescription());
        }
        
        return true;
    }
    return true;
}

